#include "decoder.h"
#include <unistd.h>
#include <errno.h>
#include <cstring>

CCSocketHandler::CCSocketHandler() 
    : handler_id(0), connected(false), recv_buffer_size(0) {
}

CCSocketHandler::~CCSocketHandler() {
    if (netfd != -1) {
        close(netfd);
    }
}

int CCSocketHandler::Init() {
    if (netfd == -1) return ERR_SOCKET;
    
    // Create decoder
    decoder.reset(CreateDecoder());
    if (!decoder) {
        return ERR_MEMORY;
    }
    
    connected = false;
    recv_buffer_size = 0;
    
    return ERR_SUCCESS;
}

int CCSocketHandler::InputNotify() {
    if (netfd == -1) return ERR_SOCKET;
    
    // Read data
    ssize_t bytes_read = read(netfd, recv_buffer + recv_buffer_size, 
                             sizeof(recv_buffer) - recv_buffer_size);
    
    if (bytes_read < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            return ERR_SUCCESS; // No more data
        }
        return ERR_SOCKET;
    }
    
    if (bytes_read == 0) {
        // Connection closed by peer
        OnClose();
        return ERR_SUCCESS;
    }
    
    recv_buffer_size += bytes_read;
    
    // Process data through decoder
    int processed = decoder->ParsePacket(recv_buffer, recv_buffer_size, this, &wspack);
    if (processed < 0) {
        return processed;
    }
    
    // Move remaining data to beginning of buffer
    if (processed > 0 && static_cast<size_t>(processed) < recv_buffer_size) {
        memmove(recv_buffer, recv_buffer + processed, recv_buffer_size - processed);
        recv_buffer_size -= processed;
    } else if (processed > 0) {
        recv_buffer_size = 0;
    }
    
    return ERR_SUCCESS;
}

int CCSocketHandler::OutputNotify() {
    // Default implementation - override in derived classes
    return ERR_SUCCESS;
}

int CCSocketHandler::HangupNotify() {
    OnClose();
    return ERR_SUCCESS;
}

int CCSocketHandler::OnConnected() {
    connected = true;
    return ERR_SUCCESS;
}

int CCSocketHandler::OnClose() {
    if (connected) {
        connected = false;
        if (netfd != -1) {
            close(netfd);
            netfd = -1;
        }
    }
    return ERR_SUCCESS;
}

int CCSocketHandler::OnTimeout() {
    return ERR_SUCCESS;
}

int CCSocketHandler::Send(CCPacketBase* packet) {
    if (!packet || netfd == -1 || !connected) {
        return ERR_SOCKET;
    }
    
    return Send(packet->GetData(), packet->GetSize());
}

int CCSocketHandler::Send(const char* data, size_t size) {
    if (!data || size == 0 || netfd == -1 || !connected) {
        return ERR_SOCKET;
    }
    
    ssize_t bytes_sent = write(netfd, data, size);
    if (bytes_sent < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            return ERR_SUCCESS; // Would block
        }
        return ERR_SOCKET;
    }
    
    if (static_cast<size_t>(bytes_sent) != size) {
        return ERR_SOCKET; // Partial send
    }
    
    return ERR_SUCCESS;
}

ICC_Decoder* CCSocketHandler::CreateDecoder() {
    return nullptr; // Override in derived classes
}

int CCSocketHandler::HandleData(const char* data, size_t size) {
    // Default implementation - override in derived classes
    return ERR_SUCCESS;
}

int CCSocketHandler::OnPacketComplete(CCPacketBase* packet) {
    // Default implementation - override in derived classes
    return ERR_SUCCESS;
}